import { shallowReactive } from "vue";

/**
 * 绑定对象值
 */
export class BindingObject<T> {
  private readonly _bindings = new Map<object, Map<string | number | symbol, number>>();

  value: T;

  private constructor(value: T) {
    this.value = value;
  }

  static create<T>(value: T) {
    return shallowReactive(new BindingObject(value));
  }

  private _setBindingValue(value: any) {
    for (const [target, bindings] of this._bindings) {
      if (!bindings) continue;
      for (const [key] of bindings) {
        (target as any)[key] = value;
      }
    }
  }

  addBinding<TTarget extends object, TKey extends keyof TTarget>(target: TTarget, key: TKey) {
    let bindings = this._bindings.get(target);
    if (!bindings) {
      bindings = new Map();
      this._bindings.set(target, bindings);
    }
    if (!bindings.has(key)) {
      bindings.set(key, 1);
    }
    return this;
  }

  removeBinding<TTarget extends object, TKey extends keyof TTarget>(target: TTarget, key?: TKey) {
    const bindings = this._bindings.get(target);
    if (bindings) {
      if (key != null) {
        const count = bindings.get(key);
        if (count) {
          if (count === 1) {
            bindings.delete(key);
          } else {
            bindings.set(key, count - 1);
          }
        }
      } else {
        bindings.clear();
        this._bindings.delete(target);
      }
    }
    return this;
  }
}
